# -*- coding : "utf-8" -*-
# @姓名       : GUI
# @日期       : 2023/2/12 19:51
# @FileName  ： cases.py
# @Software  ： PyCharm
import logging
from pathlib import Path
import allure
import pytest
from commons.exchange import Exchange
from commons.files import YamlFile
from commons.models import CaseInfo
from commons.session import Session
from commons import settings


session = Session(settings.base_url)

logger = logging.getLogger(__name__)

# yaml用例存放目录
_case_path = Path(settings.case_path)
exchanger = Exchange(settings.extract_path)


class TestAPI:  # 一个可以被pytest识别的测试类
    @classmethod  # 类方法
    def find_yaml_case(cls, case_path: Path = _case_path):
        """
        寻找和加载yaml文件
        :return:
        """

        yaml_path_list = case_path.glob("**/test_*.yaml")
        for yaml_path in yaml_path_list:
            logger.info(f"load file {yaml_path=}")

            file = YamlFile(yaml_path)  # 自动读取yaml文件
            case_info = CaseInfo(**file)  # 自动验证yaml格式

            logger.debug(case_info.to_yaml())  # 把case_info 转成字符串，然后记录日志

            case_func = cls.new_case(case_info)  # 从yaml格式转为pytest格式
            setattr(cls, f"{yaml_path.name}", case_func)  # 把pytest格式添加到类中

    @classmethod  # 类方法
    def new_case(cls, case_info: CaseInfo):

        ddt_data = case_info.ddt()
        ddt_title = [data.title for data in ddt_data]

        @pytest.mark.parametrize("case_info", ddt_data, ids=ddt_title)
        def test_func(self, case_info: CaseInfo):
            allure.dynamic.epic(case_info.epic)
            allure.dynamic.feature(case_info.feature)
            allure.dynamic.story(case_info.story)
            allure.dynamic.title(case_info.title)

            logger.info(f"用例开始执行: {case_info.title}".center(80, "="))

            # 0. 变量替换
            new_case_info = exchanger.replace(case_info)
            logger.info("1. 正在注入变量...")
            logger.debug(f"{exchanger.file}")
            # 1. 发送请求
            logger.info("2. 正在请求接口...")
            resp = session.request(**new_case_info.request)

            logger.info("3. 正在提取变量...")
            # 2. 保存变量（接口关联）
            for var_name, extract_info in new_case_info.extract.items():
                # print(var_name, extract_info)
                exchanger.extract(resp, var_name, *extract_info)

            # 3. 断言
            logger.info("4. 正在断言...")
            assert_case_info = exchanger.replace(case_info)  # 为断言加载变量
            assert_case_info.assert_all()  # 执行断言

            logger.info(f"用例执行结束: {case_info.title}".center(80, "="))

        return test_func
